接著使用Expression來解決Reflection版本問題,主要是利用Expression特性 : 「可以在Runtime時期動態建立方法」
來解決問題。
在這之前需要先有一個重要概念 : 「從結果反推最簡潔代碼」
優化效率,舉個例子 : 以前初學程式時一個經典題目「打印正三角型星星」做出一個長度為3的正三角,常見作法會是迴圈+遞迴方式
void Main()
{
Print(3,0);
}
static void Print(int length, int spaceLength)
{
if (length < 0)
return;
else
Print(length - 1, spaceLength + 1);
for (int i = 0; i < spaceLength; i++)
Console.Write(" ");
for (int i = 0; i < length; i++)
Console.Write("* ");
Console.WriteLine("");
}
但其實這個題目在已經知道長度的情況下,可以被改成以下代碼
Console.WriteLine(" * ");
Console.WriteLine(" * * ");
Console.WriteLine("* * * ");
這個概念很重要,因為是從結果反推代碼,所以邏輯直接、效率快
,而Dapper就是使用此概念來動態建立方法。
舉例 : 假設有一段代碼如下,我們可以從結果得出
void Main()
{
using (var cn = Connection)
{
var result = cn.Query<User>("select N'暐翰' Name,26 Age").First();
}
}
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
假如系統能幫忙生成以下邏輯方法,那麼效率會是最好的
User 動態方法(IDataReader reader)
{
var user = new User();
var value = reader[0];
if( !(value is System.DBNull) )
user.Name = (string)value;
value = reader[1];
if( !(value is System.DBNull) )
user.Age = (int)value;
return user;
}
另外上面例子可以看出對Dapper來說SQL Select對應Class屬性順序很重要
,所以後面會講解Dapper在緩存的算法特別針對此優化。